package model.data.tableModel.person;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import enums.Status;
import model.Utility;
import model.data.interfaces.IFinishable;
import model.data.tableModel.TableControl;
import model.handler.databaseHandling.QueryFactory;

/**
 * Superclass representing important information about a person.
 * <p>
 * Is implemented by <code>Staff</code> and <code>Customer</code>.
 * 
 * version %I%, %G%
 * @see Staff
 * @see Customer
 */
public class Person implements IFinishable{
	
	private final static Logger debug = LogManager.getLogger("DEBUG");
	
	private final int personID;
	private String firstName;
	private String lastName;
	private int room;
	private String email;
	private Status status;
	
	protected Person(final int personID, final String firstName, final String lastName, final int room, Status status, final String email) {
		assert personID >=0;
		assert room >=0;
		assert firstName != null && !"".equals(firstName);
		assert lastName != null && !"".equals(lastName);
		assert email != null && !"".equals(email);
		
		this.personID = personID;
		this.firstName = firstName;
		this.lastName = lastName;
		this.room = room;
		this.status = status;
		this.email = email;
	}
	
	public static Person createNewPerson(final String firstName, final String lastName, final int room, Status status, final String email){
		int id = TableControl.getCentralCounter();
		debug.debug("New Person created " + firstName + " " + lastName + " ID: " + id);
		return new Person(id, firstName, lastName, room, status, email);
	}
	
	public static Person createExistingPerson(final int personID, final String firstName, final String lastName, final int room, Status status, final String email){
		debug.debug("Existing Person created " + firstName + " " + lastName + " ID: " + personID);
		return new Person(personID, firstName, lastName, room, status, email);
	}
	
	@Override
	public String toString(){
		return Utility.concatStrings(firstName, " ", lastName, " (", String.valueOf(room), ")");
	}
	
	@Override
	public boolean writeToDB() {
		return QueryFactory.writePersonToDB(false, personID, firstName, lastName, room, status, email);
	}
	
	@Override
	public boolean writeUpdateToDB(){
		return QueryFactory.writePersonToDB(true, personID, firstName, lastName, room, status, email);
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((firstName == null) ? 0 : firstName.hashCode());
		result = prime * result + ((lastName == null) ? 0 : lastName.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (firstName == null) {
			if (other.firstName != null)
				return false;
		} else if (!firstName.equals(other.firstName))
			return false;
		if (lastName == null) {
			if (other.lastName != null)
				return false;
		} else if (!lastName.equals(other.lastName))
			return false;
		return true;
	}

	public void setPerson(Person person) {
		this.firstName = person.getFirstName();
		this.lastName = person.getLastName();
		this.room = person.getRoom();
	}
	
	/* GETTER AND SETTER BELOW */

	public void setMail(String mail) {
		this.email = mail;
	}
	
	public void setRoom(int room){
		this.room = room;
	}
	
	@Override
	public void setStatus(Status status) {
		this.status = status;
		this.writeUpdateToDB();
	}

	public int getPersonID() {
		return personID;
	}

	public String getFirstName() {
		return firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public int getRoom() {
		return room;
	}

	public String getEmail() {
		return email;
	}

	public Status getStatus() {
		return status;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	
	public void setFirstName(String firstName){
		this.firstName = firstName;
	}
}
